﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace ProgramCat
{
  


    /// <summary>
    /// 插件初始化委托
    /// </summary>
    /// <returns></returns>
    public delegate int Delegate_Init();
    /// <summary>
    /// Request 开始委托
    /// </summary>
    /// <param name="request_ptr">变量指针  字节集</param>
    /// <param name="requestLength">数据长度</param>
    /// <returns>数据指针</returns>
    public delegate int Delegate_OnRequest(int request_ptr, int requestLength);
    /// <summary>
    /// 插件信息
    /// </summary>
    public class EPlug
    {
        /// <summary>
        /// 插件指针
        /// </summary>
        public int plugPtr;
        /// <summary>
        /// 文件名称
        /// </summary>
        public string fileName;
        /// <summary>
        /// 插件名称
        /// </summary>
        public string plugName = "";
        /// <summary>
        /// 作者名称
        /// </summary>
        public string plugAuthor = "";
        /// <summary>
        /// 版本号
        /// </summary>
        public string version = "";

        public Delegate_Init initFunction = null;

        public Delegate_OnRequest onRequestFunction = null;
        public EPlug(int plugPtr,string fileName)
        {
            this.plugPtr = plugPtr;
            this.fileName = fileName;
        }
    }
    /// <summary>
    /// 定义com必要接口
    /// </summary>
    [ComVisible(true)]
    [Guid(ComHelperClass.s_IID_IComClass)]
    public interface IAppCom
    {
        [DispId(1)]
        string TestProperty { get; set; }
        [DispId(2)]
        string LoadAllPlugs(string CurrentDirectory);
        [DispId(3)]
        byte[] OnRequest(int plugPtr,byte[] data);


    }
    /// <summary>
    /// 实现com类
    /// </summary>
    [ComVisible(true)]
    [Guid(ComHelperClass.s_CLSID_ComClass)]
    public class AppCom : IAppCom
    {
        private static string plugInPath = "";
        /// <summary>
        /// 插件列表
        /// </summary>
        private List<EPlug> plugInfos = new List<EPlug>();
        public List<EPlug> PlugInfos { get { return plugInfos; } }
        public string TestProperty { get; set; }
        /// <summary>
        /// 尝试加载所有插件
        /// </summary>
        /// <param name="CurrentDirectory">插件目录</param>
        /// <returns>返回插件列表json</returns>
        public string LoadAllPlugs(string CurrentDirectory)
        {
            plugInPath = CurrentDirectory + @"\Scripts\ProgramCat\PlugIn\";
            if (!Directory.Exists(plugInPath))
            {
                Directory.CreateDirectory(plugInPath);
            }
            if (plugInPath == "")
                return "";
            //遍历目录
            DirectoryInfo theFolder = new DirectoryInfo(plugInPath);
            foreach (var file in theFolder.GetFiles("*.dll"))
            {
                //调用winapi动态载入插件 返回DLL句柄
                int plugPtr = DLLWrapper.LoadSDK(file.FullName);
                
                if (plugPtr == 0)
                {
                    continue;
                }
                EPlug ePlug = new EPlug(plugPtr, file.Name);
                //调用插件初始化
                if (ePlug.Init())
                {
                    plugInfos.Add(ePlug);
                }
            }
            //序列化类到json
            return Newtonsoft.Json.JsonConvert.SerializeObject(plugInfos); ;
        }
        /// <summary>
        /// 尝试调用插件 进行Request数据处理
        /// </summary>
        /// <param name="plugPtr">插件DLL句柄</param>
        /// <param name="data">编程猫插件拦截传入的数据</param>
        /// <returns></returns>
        public byte[] OnRequest(int plugPtr, byte[] data)
        {
            //取回对应插件
            EPlug ePlug = PlugInfos.Find((x) =>
            {
                return x.plugPtr == plugPtr;
            });
            //DLL动态调用OnRequest函数Call
            return ePlug?.OnRequest(data);
        }
    }
}
